package com.example.demoserver.service.impl;

import com.example.demoserver.controller.Util;
import com.example.demoserver.entity.ExamQuestionInsert;
import com.example.demoserver.entity.TrainQueoptions;
import com.example.demoserver.entity.TrainQuestions;
import com.example.demoserver.entity.TrainUserquesions;
import com.example.demoserver.service.TrainQueoptionsService;
import com.example.demoserver.service.TrainQuestionsService;
import com.example.demoserver.service.TrainUserquesionsService;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.apache.http.message.BasicHeader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Service
@EnableScheduling
public class PollingService implements SchedulingConfigurer {

    @Value("${examServer.ip}")
    private String ip;
    @Value("${examServer.port}")
    private String port;
    @Value("${inteUrl.dir}")
    private String dir;
    @Value("${examServer.pollingTime}")
    private String pollingTime;
    @Autowired
    private TrainUserquesionsService trainUserquesionsService;
    @Autowired
    private TrainQuestionsService trainQuestionsService;
    @Autowired
    private TrainQueoptionsService trainQueoptionsService;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.addFixedRateTask(() -> {
            try {
                run();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }, Long.parseLong(String.valueOf(Integer.parseInt(pollingTime) * 1000)));
    }

    public void run() throws IOException {

        //轮询
        //TimeUnit.SECONDS.sleep(Integer.parseInt(pollingTime));
        //本地信息
        TrainUserquesions trainUserquesions4 = trainUserquesionsService.select();
        if (trainUserquesions4 != null) {
            Integer userId = trainUserquesions4.getUserid();
            String token = trainUserquesions4.getToken();
            //获取分配信息
            TrainUserquesions trainUserquesions5 = getUserQue(userId, token);
            if (trainUserquesions5 != null && trainUserquesions5.getSaveversion() != 0) {
                String result1 = getHttp("http://" + ip + ":" + port + "/userque/ispulling?userId=" + userId + "&version=" + trainUserquesions4.getSaveversion(), token);
                ObjectMapper objectMapper1 = new ObjectMapper();
                // 将JSON字符串转换为Map
                JsonNode rootNode1 = objectMapper1.readValue(result1, JsonNode.class);
                JsonNode dataNode1 = rootNode1.get("Code");
                if (dataNode1.toString().equals("200")) {
                    //没有新版本 对比试题哈希值 并拉取不同值
                    if (rootNode1.get("Data").isNull()) {
                        List<TrainQuestions> list = trainQuestionsService.select(null);
                        for (TrainQuestions t : list) {
                            String result2 = getHttp("http://" + ip + ":" + port + "/question/isupdate?queId=" + t.getQueid() + "&hashCode=" + t.getQuehashcode(), token);
                            if (!result2.equals("")) {
                                ExamQuestionInsert examQuestionInsert = objectMapper1.readValue(result2, ExamQuestionInsert.class);
                                if (examQuestionInsert != null) {
                                    TrainQuestions trainQuestions = examQuestionInsert.getExamQuestions();
                                    trainQuestions.setQueid(trainQuestions.getId());
                                    trainQuestions.setId(t.getId());
                                    trainQuestionsService.updateById(trainQuestions);
                                    trainQueoptionsService.deleteByQueId(t.getQueid());
                                    trainQueoptionsService.saveBatch(examQuestionInsert.getExamQueoptions());
                                    if (trainQuestions.getPreclass() != null) {
                                        saveTemplate("http://" + ip + ":" + port + "/question/templateurl?id=" + t.getQueid(), token, trainQuestions.getPreclass());
                                    }
                                }
                            }

                        }
                    } else {
                        //有新版本清空数据库 重新拉取
                        deleteTem();
                        JsonNode dataNode2 = rootNode1.get("Data");
                        TrainUserquesions trainUserquesions1 = objectMapper1.readValue(dataNode2.toString(), TrainUserquesions.class);
                        trainQuestionsService.deleteAll();
                        trainQueoptionsService.deleteAll();
                        String res = postHttp("http://" + ip + ":" + port + "/question/pulling", token, trainUserquesions1);
                        getData(res, token);
                        trainUserquesions1.setId(trainUserquesions4.getId());
                        trainUserquesionsService.updateById(trainUserquesions1);
                    }
                }
            } else {
                //没有分配信息，获取标准题库
                String res = getHttp("http://" + ip + ":" + port + "/train/pulling", token);
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode dataJson = objectMapper.readValue(res, JsonNode.class);
                List<Integer> ids = new ArrayList<>();
                //遍历标准题库
                for (int i = 0; i < dataJson.size(); i++) {
                    JsonNode Entity = dataJson.get(i);
                    JsonNode examQueoptionsList = Entity.get("examQueoptions");
                    JsonNode examQuestion = Entity.get("examQuestions");
                    TrainQuestions trainQuestions = objectMapper.treeToValue(examQuestion, TrainQuestions.class);//标准题库题信息
                    TrainQuestions t = trainQuestionsService.selectByqueId(trainQuestions.getId());//本地题库题信息
                    ids.add(trainQuestions.getId());
                    //如果本地没有该题则保存
                    if (t == null) {
                        trainQuestions.setQueid(trainQuestions.getId());
                        trainQuestionsService.save(trainQuestions);
                        List<TrainQueoptions> optionList = new ArrayList<>();
                        for (JsonNode elementNode : examQueoptionsList) {
                            TrainQueoptions trainQueoptions = objectMapper.treeToValue(elementNode, TrainQueoptions.class);
                            optionList.add(trainQueoptions);
                        }
                        trainQueoptionsService.saveBatch(optionList);
                        if (trainQuestions.getPreclass() != null) {
                            saveTemplate("http://" + ip + ":" + port + "/question/templateurl?id=" + trainQuestions.getQueid(), token, trainQuestions.getPreclass());
                        }
                    } else {
                        //如果本地有该题且两个题目hashcode不同则更新试题信息、试题选项、试题模板
                        if (!t.getQuehashcode().equals(trainQuestions.getQuehashcode())) {
                            trainQuestions.setId(t.getId());
                            trainQuestionsService.updateById(trainQuestions);
                            trainQueoptionsService.deleteByQueId(t.getQueid());
                            List<TrainQueoptions> optionList = new ArrayList<>();
                            for (JsonNode elementNode : examQueoptionsList) {
                                TrainQueoptions trainQueoptions = objectMapper.treeToValue(elementNode, TrainQueoptions.class);
                                optionList.add(trainQueoptions);
                            }
                            trainQueoptionsService.saveBatch(optionList);
                            if (trainQuestions.getPreclass() != null) {
                                saveTemplate("http://" + ip + ":" + port + "/question/templateurl?id=" + t.getQueid(), token, trainQuestions.getPreclass());
                            }
                        }
                    }

                }
                //将本地多余题目删除
                List<TrainQuestions> l = trainQuestionsService.select(null);
                for (TrainQuestions t : l) {
                    if (!ids.contains(t.getQueid())) {
                        trainQuestionsService.deleteById(t.getId());
                        trainQueoptionsService.deleteByQueId(t.getQueid());
                        if(t.getPreclass()!=null||!t.getPreclass().equals("")){
                            File file = new File(dir + "/" + t.getPreclass() + ".inet");
                            file.delete();
                        }

                    }
                }
                TrainUserquesions t = trainUserquesions4;
                t.setQuestionids("");
                t.setSaveversion(0);
                trainUserquesionsService.updateById(trainUserquesions4);

            }
        }
    }


    public TrainUserquesions getUserQue(Integer userId, String token) throws IOException {
        String result = getHttp("http://" + ip + ":" + port + "/userque/selectuserque?userId=" + userId, token);

        ObjectMapper objectMapper = new ObjectMapper();
        // 将JSON字符串转换为Map
        JsonNode rootNode = objectMapper.readValue(result, JsonNode.class);
        JsonNode dataNode = rootNode.get("Data");
        TrainUserquesions trainUserquesions = objectMapper.treeToValue(dataNode, TrainUserquesions.class);
        return trainUserquesions;
    }

    public String getHttp(String str, String token) throws IOException {
        URL url = new URL(str);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        connection.setRequestProperty("Cookie", "token=" + token);

        // 获取响应状态码
        int statusCode = connection.getResponseCode();

        // 获取响应内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        String line;
        StringBuilder responseContent = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            responseContent.append(line);
        }
        reader.close();

        // 关闭连接
        connection.disconnect();
        return responseContent.toString();
    }

    public String postHttp(String str, String token, Object sendData) throws IOException {
        URL url = new URL(str);
        // 创建HttpURLConnection对象
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        // 设置请求方法为POST
        connection.setRequestMethod("POST");
        CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        connection.setRequestProperty("Cookie", "token=" + token);

        // 设置请求头，例如设置Content-Type为application/x-www-form-urlencoded
        connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");

        // 开启输出流，用于写入请求数据
        connection.setDoOutput(true);

        // 准备要发送的数据
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonData = objectMapper.writeValueAsString(sendData);
        // 将数据写入输出流
        try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
            outputStream.writeBytes(jsonData);
        }

        // 获取响应码
        int responseCode = connection.getResponseCode();


        // 获取响应内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
        String line;
        StringBuilder responseContent = new StringBuilder();
        while ((line = reader.readLine()) != null) {
            responseContent.append(line);
        }
        reader.close();

        connection.disconnect();
        return responseContent.toString();
    }


    public String getData(String result, String token) throws IOException {

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode dataJson = objectMapper.readValue(result, JsonNode.class);
        for (int i = 0; i < dataJson.size(); i++) {
            JsonNode Entity = dataJson.get(i);
            JsonNode examQueoptionsList = Entity.get("examQueoptions");
            JsonNode examQuestion = Entity.get("examQuestions");
            List<TrainQueoptions> optionList = new ArrayList<>();
            for (JsonNode elementNode : examQueoptionsList) {
                TrainQueoptions trainQueoptions = objectMapper.treeToValue(elementNode, TrainQueoptions.class);
                optionList.add(trainQueoptions);
            }

            TrainQuestions trainQuestions = objectMapper.treeToValue(examQuestion, TrainQuestions.class);
            trainQuestions.setQueid(trainQuestions.getId());
            trainQuestionsService.save(trainQuestions);
            trainQueoptionsService.saveBatch(optionList);
            if (trainQuestions.getPreclass() != null) {
                saveTemplate("http://" + ip + ":" + port + "/question/templateurl?id=" + trainQuestions.getQueid(), token, trainQuestions.getPreclass());
            }

        }

        return result;
    }

    public void saveTemplate(String str, String token, String filename) throws IOException {
        URL url = new URL(str);
        // 打开连接
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        CookieManager cookieManager = new CookieManager();
        cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
        connection.setRequestProperty("Cookie", "token=" + token);

        // 获取响应状态码
        int statusCode = connection.getResponseCode();
        if (statusCode != 404) {
            // 获取响应内容
            InputStream inputStream = connection.getInputStream();
            // 定义要保存文件的路径和文件名，以保存到当前目录下的test.bin为例
            File outputFile = new File(dir + "/" + filename + ".inet");
            File folder = new File(dir);

            if (!folder.exists()) {
                try {
                    Files.createDirectories(Paths.get(dir));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            Files.copy(inputStream, outputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            // 关闭连接
            inputStream.close();


        }
        connection.disconnect();


    }

    public void deleteTem() {
        String folderPath = dir; // 替换为实际的文件夹路径
        File folder = new File(folderPath);
        if (folder.exists() && folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        file.delete();
                    }
                }
            }
        }
    }


//    @Override
//    public void run(Integer userId, String token) throws IOException{
//        running.set(true);
//
//        trainQuestionsService.deleteAll();
//        trainQueoptionsService.deleteAll();
//        //获取用户题库
//        TrainUserquesions trainUserquesions=getUserQue(userId,token);
//        if(trainUserquesions!=null&&trainUserquesions.getQuestionids()!=null){
//            //拉取题库
//            String res=postHttp("http://" + ip + ":" + port + "/question/pulling",token,trainUserquesions);
//            getData(res, token);
//        }else{
//            String res=getHttp("http://" + ip + ":" + port + "/train/pulling",token);
//            getData(res, token);
//        }
//
//        //轮询
//        while (running.get()) {
//            try {
//                TimeUnit.SECONDS.sleep(10);
//                //获取分配信息
//                TrainUserquesions trainUserquesions4=getUserQue(userId,token);
//                if(trainUserquesions4!=null&&trainUserquesions4.getQuestionids()!=null){
//                    //有分配信息，检查是否有更新
//                    String result1=getHttp("http://" + ip + ":" + port + "/userque/ispulling?userId=" + userId+"&version="+trainUserquesions4.getSaveversion(),token);
//                    ObjectMapper objectMapper1 = new ObjectMapper();
//                    // 将JSON字符串转换为Map
//                    JsonNode rootNode1 = objectMapper1.readValue(result1, JsonNode.class);
//                    JsonNode dataNode1 = rootNode1.get("Code");
//                    if(dataNode1.toString().equals("200")){
//                        //没有新版本 对比试题哈希值 并拉取不同值
//                        if(rootNode1.get("Data").isNull()){
//                            List<TrainQuestions> list=trainQuestionsService.select(null);
//                            for (TrainQuestions t:list) {
//                                String result2=getHttp("http://" + ip + ":" + port + "/question/isupdate?queId=" + t.getQueid()+"&hashCode="+t.getQuehashcode(),token);
//                                if(!result2.equals("")){
//                                    ExamQuestionInsert examQuestionInsert = objectMapper1.readValue(result2, ExamQuestionInsert.class);
//                                    if(examQuestionInsert!=null){
//                                        TrainQuestions trainQuestions=examQuestionInsert.getExamQuestions();
//                                        trainQuestions.setQueid(trainQuestions.getId());
//                                        trainQuestions.setId(t.getId());
//                                        trainQuestionsService.updateById(trainQuestions);
//                                        trainQueoptionsService.deleteByQueId(t.getQueid());
//                                        trainQueoptionsService.saveBatch(examQuestionInsert.getExamQueoptions());
//                                        if(trainQuestions.getPreclass()!=null){
//                                            saveTemplate("http://" + ip + ":" + port + "/question/templateurl?id="+t.getQueid(),token,trainQuestions.getPreclass());
//
//                                        }
//                                    }
//                                }
//
//                            }
//                        }else{
//                            //有新版本清空数据库 重新拉取
//                            JsonNode dataNode2 = rootNode1.get("Data");
//                            TrainUserquesions trainUserquesions1=objectMapper1.readValue(dataNode2.toString(), TrainUserquesions.class);
//                            trainQuestionsService.deleteAll();
//                            trainQueoptionsService.deleteAll();
//                            String res=postHttp("http://" + ip + ":" + port + "/question/pulling",token,trainUserquesions1);
//                            getData(res, token);
//                        }
//                    }
//                }else{
//                    //没有分配信息，获取标准题库
//                    String res=getHttp("http://" + ip + ":" + port + "/train/pulling",token);
//                    ObjectMapper objectMapper = new ObjectMapper();
//                    JsonNode dataJson = objectMapper.readValue(res, JsonNode.class);
//                    List<Integer> ids=new ArrayList<>();
//                    //遍历标准题库
//                    for (int i = 0; i < dataJson.size(); i++) {
//                        JsonNode Entity = dataJson.get(i);
//                        JsonNode examQueoptionsList = Entity.get("examQueoptions");
//                        JsonNode examQuestion = Entity.get("examQuestions");
//                        TrainQuestions trainQuestions = objectMapper.treeToValue(examQuestion, TrainQuestions.class);//标准题库题信息
//                        TrainQuestions t=trainQuestionsService.selectByqueId(trainQuestions.getId());//本地题库题信息
//                        ids.add(trainQuestions.getId());
//                        //如果本地没有该题则保存
//                        if(t==null){
//                            trainQuestions.setQueid(trainQuestions.getId());
//                            trainQuestionsService.save(trainQuestions);
//                            List<TrainQueoptions> optionList = new ArrayList<>();
//                            for (JsonNode elementNode : examQueoptionsList) {
//                                TrainQueoptions trainQueoptions = objectMapper.treeToValue(elementNode, TrainQueoptions.class);
//                                optionList.add(trainQueoptions);
//                            }
//                            trainQueoptionsService.saveBatch(optionList);
//                        }else{
//                            //如果本地有该题且两个题目hashcode不同则更新试题信息、试题选项、试题模板
//                            if(!t.getQuehashcode().equals(trainQuestions.getQuehashcode())){
//                                trainQuestions.setId(t.getId());
//                                trainQuestionsService.updateById(trainQuestions);
//                                trainQueoptionsService.deleteByQueId(trainQuestions.getId());
//                                List<TrainQueoptions> optionList = new ArrayList<>();
//                                for (JsonNode elementNode : examQueoptionsList) {
//                                    TrainQueoptions trainQueoptions = objectMapper.treeToValue(elementNode, TrainQueoptions.class);
//                                    optionList.add(trainQueoptions);
//                                }
//                                trainQueoptionsService.saveBatch(optionList);
//                                if(trainQuestions.getPreclass()!=null){
//                                    saveTemplate("http://" + ip + ":" + port + "/question/templateurl?id="+t.getQueid(),token,trainQuestions.getPreclass());
//                                }
//                            }
//                        }
//
//                    }
//                    //将本地多余题目删除
//                    List<TrainQuestions> l=trainQuestionsService.select(null);
//                    for (TrainQuestions t:l) {
//                        if(!ids.contains(t.getQueid())){
//                            trainQuestionsService.deleteById(t.getId());
//                            trainQueoptionsService.deleteByQueId(t.getQueid());
//                        }
//
//                    }
//                }
//
//
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
//    }
//
//    @Override
//    public void run() {
//
//    }
}
